/**
 * 
 */
package com.wubo.common.io;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**拦截输出流的close和flush方法，<b>非单例模式</b>
 * 应用场景：当我们把流交给下一个节点去，我们不能确定下一个节点会不会关掉流，
 * 而我们又想在下个节点调用完后继续使用流，这时我们需要对close或flush方法进行拦截
 * @author WuBo
 * @CreateDate 2010-9-29
 * @version 1.0.01
 */
public class ProxyOutputStream extends OutputStream {

	private OutputStream os;

	private ProxyOutputStream(OutputStream os) {
		this.os = os;
	}
	
	public static OutputStream createInstance(OutputStream os, boolean allowClose, boolean allowFlush){
		return (OutputStream) Proxy.newProxyInstance(
			ProxyOutputStream.class.getClassLoader(),
			new Class[]{ProxyOutputStream.class}, 
			new DefaultInvocationHandler(
					new ProxyOutputStream(os), 
					allowClose, 
					allowFlush)
			);
	}
	
	
	protected static class DefaultInvocationHandler implements InvocationHandler {
		
		private OutputStream target;
		
		private boolean allowClose;
		
		private boolean allowFlush;
		
		public DefaultInvocationHandler(OutputStream os, boolean allowClose, boolean allowFlush){
			target = os;
			this.allowClose = allowClose;
			this.allowFlush = allowFlush;
		}
		
		public Object invoke(Object proxy, Method method, Object[] args)
				throws Throwable {
			if( !allowClose && "close".equals(method.getName()) ){
					return null;
			}
			if( !allowFlush && "flush".equals(method.getName()) ){
				return null;
			}
			return method.invoke(target, args);
		}
	}
	/**
	 * 实际close方法调用
	 * @throws IOException
	 */
	public void realClose() throws IOException {
		os.close();
	}
	/**
	 * 实际flush方法调用
	 */
	public void realFlush() throws IOException {
		os.flush();
	}

	@Override
	public void write(int b) throws IOException {
		os.write(b);
	}

}
